module Controle (op, fn, rt, selwsource, selregdest,
    writereg, writeov, selimregb, selsarega, selalushift,
    aluop, unsig, shiftop, mshw, lshw, msm, msl,
    readmem, writemem, selbrjumpz, seltipopc, compop);

    // OpCode; Function; Registrador Fonte ou Destino.
	input   [5:0]   op;
	input   [5:0]   fn;
	input   [4:0]   rt;

	// Sinais do Controle.
	output  [2:0]   selwsource;
	output  [1:0]   selregdest;
	output  [0:0]   writereg;
	output  [0:0]   writeov;
	output  [0:0]   selimregb;
	output  [0:0]   selsarega;
	output	[0:0]	selalushift;
	output  [2:0]   aluop;
	output	[0:0]	unsig;
	output  [1:0]	shiftop;
	output	[0:0]	mshw;
	output	[0:0]   lshw;
	output	[2:0]	msm;
	output	[2:0]	msl;
	output	[0:0]	readmem;
	output	[0:0]	writemem;
	output	[1:0]	selbrjumpz;
	output	[1:0]	seltipopc;
	output	[2:0]	compop;

    // Registrador auxiliar:
    reg [32:0] linha;

    // Sinais de saida:
    assign selimregb = linha[32];
    assign selsarega = linha[31];
    assign selbrjumpz = linha[30:29];
    assign selregdest = linha[28:27];
    assign selwsource = linha[26:24];
    assign writereg = linha[23];
    assign writeov = linha[22];
    assign unsig = linha[21];
    assign shiftop = linha[20:19];
    assign aluop = linha[18:16];
    assign selalushift = linha[15];
    assign compop = linha[14:12];
    assign seltipopc = linha[11:10];
    assign readmem = linha[9];
    assign writemem = linha[8];
    assign mshw = linha[7];
    assign lshw = linha[6];
    assign msm = linha[5:3];
    assign msl = linha[2:0];

    // Atualizacao dos sinais de saida:
    always @(op or fn or rt) begin

        // SLL
        if ((op == 6'b000000) && (fn == 6'b000000)) begin
            linha <= 33'b01000100011X10XXX1XXXXX00XXXXXXXX;
            // $display(">>> Instruction: SLL;");
        end

        // SRL
        if ((op == 6'b000000) && (fn == 6'b000010)) begin
            linha <= 33'b01000100011X00XXX1XXXXX00XXXXXXXX;
            // $display(">>> Instruction: SRL;");
        end

        // SRA
        if ((op == 6'b000000) && (fn == 6'b000011)) begin
            linha <= 33'b01000100011X01XXX1XXXXX00XXXXXXXX;
            // $display(">>> Instruction: SRA;");
        end

        // SLLV
        if ((op == 6'b000000) && (fn == 6'b000100)) begin
            linha <= 33'b00000100011X10XXX1XXXXX00XXXXXXXX;
            // $display(">>> Instruction: SLLV;");
        end

        // SRLV
        if ((op == 6'b000000) && (fn == 6'b000110)) begin
            linha <= 33'b00000100011X00XXX1XXXXX00XXXXXXXX;
            // $display(">>> Instruction: SRLV;");
        end

        // SRAV
        if ((op == 6'b000000) && (fn == 6'b000111)) begin
            linha <= 33'b00000100011X01XXX1XXXXX00XXXXXXXX;
            // $display(">>> Instruction: SRAV;");
        end

        // JR
        if ((op == 6'b000000) && (fn == 6'b001000)) begin
            linha <= 33'bX00111XXX0XXXXXXXXXXX0100XXXXXXXX;
            // $display(">>> Instruction: JR;");
        end

        // JALR
        if ((op == 6'b000000) && (fn == 6'b001001)) begin
            linha <= 33'bX0010101111XXXXXXXXXX0100XXXXXXXX;
            // $display(">>> Instruction: JALR;");
        end

        // ADD
        if ((op == 6'b000000) && (fn == 6'b100000)) begin
            linha <= 33'b000001000100XX0100XXXXX00XXXXXXXX;
            // $display(">>> Instruction: ADD;");
        end

        // ADDU
        if ((op == 6'b000000) && (fn == 6'b100001)) begin
            linha <= 33'b000001000111XX0100XXXXX00XXXXXXXX;
            // $display(">>> Instruction: ADDU;");
        end

        // SUB
        if ((op == 6'b000000) && (fn == 6'b100010)) begin
            linha <= 33'b000001000100XX1100XXXXX00XXXXXXXX;
            // $display(">>> Instruction: SUB;");
        end

        // SUBU
        if ((op == 6'b000000) && (fn == 6'b100011)) begin
            linha <= 33'b000001000111XX1100XXXXX00XXXXXXXX;
            // $display(">>> Instruction: SUB;");
        end

        // AND
        if ((op == 6'b000000) && (fn == 6'b100100)) begin
            linha <= 33'b00000100011XXX0000XXXXX00XXXXXXXX;
            // $display(">>> Instruction: AND;");
        end

        // OR
        if ((op == 6'b000000) && (fn == 6'b100101)) begin
            linha <= 33'b00000100011XXX0010XXXXX00XXXXXXXX;
            // $display(">>> Instruction: OR;");
        end

        // XOR
        if ((op == 6'b000000) && (fn == 6'b100110)) begin
            linha <= 33'b00000100011XXX1010XXXXX00XXXXXXXX;
            // $display(">>> Instruction: XOR;");
        end

        // NOR
        if ((op == 6'b000000) && (fn == 6'b100111)) begin
            linha <= 33'b00000100011XXX1000XXXXX00XXXXXXXX;
            // $display(">>> Instruction: NOR;");
        end

        // SLT
        if ((op == 6'b000000) && (fn == 6'b101010)) begin
            linha <= 33'b000001100110XX1100XXXXX00XXXXXXXX;
            // $display(">>> Instruction: SLT;");
        end

        // SLTU
        if ((op == 6'b000000) && (fn == 6'b101011)) begin
            linha <= 33'b000001100111XX1100XXXXX00XXXXXXXX;
            // $display(">>> Instruction: SLTU;");
        end

        // BLTZ
        if ((op == 6'b000001) && (rt == 5'b00000 )) begin
            linha <= 33'bX01011XXX0X0XXXXXX1000000XXXXXXXX;
            // $display(">>> Instruction: BLTZ;");
        end

        // BGEZ
        if ((op == 6'b000001) && (rt == 5'b00001 )) begin
            linha <= 33'bX01011XXX0X0XXXXXX0010000XXXXXXXX;
            // $display(">>> Instruction: BGEZ;");
        end

        // BLTZAL
        if ((op == 6'b000001) && (rt == 5'b10000 )) begin
            linha <= 33'bX01010011110XXXXXX1000000XXXXXXXX;
            // $display(">>> Instruction: BLTZAL;");
        end

        // BGEZAL
        if ((op == 6'b000001) && (rt == 5'b10001 )) begin
            linha <= 33'bX01010011110XXXXXX0010000XXXXXXXX;
            // $display(">>> Instruction: BGEZAL;");
        end

        // J
        if (op == 6'b000010) begin
            linha <= 33'bXX0111XXX0XXXXXXXXXXX1000XXXXXXXX;
            // $display(">>> Instruction: J;");
        end

        // JAL
        if (op == 6'b000011) begin
            linha <= 33'bXX011001111XXXXXXXXXX1000XXXXXXXX;
            // $display(">>> Instruction: JAL;");
        end

        // BEQ
        if (op == 6'b000100) begin
            linha <= 33'bX01011XXX0X0XXXXXX0000000XXXXXXXX;
            // $display(">>> Instruction: BEQ;");
        end

        // BNE
        if (op == 6'b000101) begin
            linha <= 33'bX01011XXX0X0XXXXXX1010000XXXXXXXX;
            // $display(">>> Instruction: BNE;");
        end

        // BLEZ
        if (op == 6'b000110) begin
            linha <= 33'bX01011XXX0X0XXXXXX0100000XXXXXXXX;
            // $display(">>> Instruction: BLEZ;");
        end

        // BGTZ
        if (op == 6'b000111) begin
            linha <= 33'bX01011XXX0X0XXXXXX0110000XXXXXXXX;
            // $display(">>> Instruction: BGTZ;");
        end
        
        // ADDI
        if (op == 6'b001000) begin
            linha <= 33'b100000000100XX0100XXXXX00XXXXXXXX;
            // $display(">>> Instruction: ADDI ;");
        end

        // ADDIU
        if (op == 6'b001001) begin
            linha <= 33'b100000000111XX0100XXXXX00XXXXXXXX;
            // $display(">>> Instruction: ADDIU;");
        end

        // SLTI
        if (op == 6'b001010) begin
            linha <= 33'b100000100100XX1100XXXXX00XXXXXXXX;
            // $display(">>> Instruction: SLTI;");
        end

        // SLTIU
        if (op == 6'b001011) begin
            linha <= 33'b100000100111XX1100XXXXX00XXXXXXXX;
            // $display(">>> Instruction: SLTIU;");
        end

        // ANDI
        if (op == 6'b001100) begin
            linha <= 33'b10000000011XXX0000XXXXX00XXXXXXXX;
            // $display(">>> Instruction: ANDI;");
        end

        // ORI
        if (op == 6'b001101) begin
            linha <= 33'b10000000011XXX0010XXXXX00XXXXXXXX;
            // $display(">>> Instruction: ORI;");
        end

        // XORI
        if (op == 6'b001110) begin
            linha <= 33'b10000000011XXX1010XXXXX00XXXXXXXX;
            // $display(">>> Instruction: XORI;");
        end

        // LUI
        if (op == 6'b001111) begin
            linha <= 33'bXX000001011XXXXXXXXXXXX00XXXXXXXX;
            // $display(">>> Instruction: LUI;");
        end

        // Undefined
        if (op == 6'b010000) begin linha <= 33'bXXXX11XXX0XXXXXXXXXXXXX00XXXXXXXX; end
        if (op == 6'b010001) begin linha <= 33'bXXXX11XXX0XXXXXXXXXXXXX00XXXXXXXX; end
        if (op == 6'b010010) begin linha <= 33'bXXXX11XXX0XXXXXXXXXXXXX00XXXXXXXX; end
        if (op == 6'b010011) begin linha <= 33'bXXXX11XXX0XXXXXXXXXXXXX00XXXXXXXX; end
        if (op == 6'b010100) begin linha <= 33'bXXXX11XXX0XXXXXXXXXXXXX00XXXXXXXX; end
        if (op == 6'b010101) begin linha <= 33'bXXXX11XXX0XXXXXXXXXXXXX00XXXXXXXX; end
        if (op == 6'b010110) begin linha <= 33'bXXXX11XXX0XXXXXXXXXXXXX00XXXXXXXX; end
        if (op == 6'b010111) begin linha <= 33'bXXXX11XXX0XXXXXXXXXXXXX00XXXXXXXX; end
        if (op == 6'b011000) begin linha <= 33'bXXXX11XXX0XXXXXXXXXXXXX00XXXXXXXX; end
        if (op == 6'b011001) begin linha <= 33'bXXXX11XXX0XXXXXXXXXXXXX00XXXXXXXX; end
        if (op == 6'b011010) begin linha <= 33'bXXXX11XXX0XXXXXXXXXXXXX00XXXXXXXX; end
        if (op == 6'b011011) begin linha <= 33'bXXXX11XXX0XXXXXXXXXXXXX00XXXXXXXX; end
        if (op == 6'b011100) begin linha <= 33'bXXXX11XXX0XXXXXXXXXXXXX00XXXXXXXX; end
        if (op == 6'b011101) begin linha <= 33'bXXXX11XXX0XXXXXXXXXXXXX00XXXXXXXX; end
        if (op == 6'b011110) begin linha <= 33'bXXXX11XXX0XXXXXXXXXXXXX00XXXXXXXX; end
        if (op == 6'b011111) begin linha <= 33'bXXXX11XXX0XXXXXXXXXXXXX00XXXXXXXX; end

        // LB 
        if (op == 6'b100000) begin
            linha <= 33'b100000001110XX0100XXXXX1011011011;
            // $display(">>> Instruction: LB;");
        end

        // LH
        if (op == 6'b100001) begin
            linha <= 33'b100000001110XX0100XXXXX1011011001;
            // $display(">>> Instruction: LH;");
        end

        // LWL
        if (op == 6'b100010) begin
            linha <= 33'b100000001110XX0100XXXXX1010010000;
            // $display(">>> Instruction: LWL;");
        end

        // LW
        if (op == 6'b100011) begin
            linha <= 33'b100000001110XX0100XXXXX1011001010;
            // $display(">>> Instruction: LW;");
        end

        // LBU
        if (op == 6'b100100) begin
            linha <= 33'b100000001110XX0100XXXXX1011000100;
            // $display(">>> Instruction: LBU;");
        end

        // LHU
        if (op == 6'b100101) begin
            linha <= 33'b100000001110XX0100XXXXX1011000001;
            // $display(">>> Instruction: LHU;");
        end

        // LWR
        if (op == 6'b100110) begin
            linha <= 33'b100000001110XX0100XXXXX1001000001;
            // $display(">>> Instruction: LWR;");
        end

        // Undefined
        if (op == 6'b100111) begin linha <= 33'bXXXX11XXX0XXXXXXXXXXXXX00XXXXXXXX; end

        // SB
        if (op == 6'b101000) begin
            linha <= 33'b100011XXX0X0XX0100XXXXX0111100011;
            // $display(">>> Instruction: SB;");
        end

        // SH
        if (op == 6'b101001) begin
            linha <= 33'b100011XXX0X0XX0100XXXXX0111010000;
            // $display(">>> Instruction: SH;");
        end

        // SWL
        if (op == 6'b101010) begin
            linha <= 33'b100011XXX0X0XX0100XXXXX0101000001;
            // $display(">>> Instruction: SWL;");
        end

        // SW
        if (op == 6'b101011) begin
            linha <= 33'b100011XXX0X0XX0100XXXXX0111001010;
            // $display(">>> Instruction: SW;");
        end

        // Undefined
        if (op == 6'b101100) begin linha <= 33'bXXXX11XXX0XXXXXXXXXXXXX00XXXXXXXX; end
        if (op == 6'b101101) begin linha <= 33'bXXXX11XXX0XXXXXXXXXXXXX00XXXXXXXX; end

        // SWR
        if (op == 6'b101110) begin
            linha <= 33'b100011XXX0X0XX0100XXXXX0110010000;
            // $display(">>> Instruction: SWR;");
        end

        // Undefined
        if (op == 6'b101111) begin linha <= 33'bXXXX11XXX0X0XXXXXXXXXXX00XXXXXXXX; end

        // LL
        if (op == 6'b110000) begin
            linha <= 33'b100000001110XX0100XXXXX1011001010;
            // $display(">>> Instruction: LL;");
        end

        // Undefined
        if (op == 6'b110001) begin linha <= 33'bXXXX11XXX0XXXXXXXXXXXXX00XXXXXXXX; end
        if (op == 6'b110010) begin linha <= 33'bXXXX11XXX0XXXXXXXXXXXXX00XXXXXXXX; end
        if (op == 6'b110100) begin linha <= 33'bXXXX11XXX0XXXXXXXXXXXXX00XXXXXXXX; end
        if (op == 6'b110101) begin linha <= 33'bXXXX11XXX0XXXXXXXXXXXXX00XXXXXXXX; end
        if (op == 6'b110110) begin linha <= 33'bXXXX11XXX0XXXXXXXXXXXXX00XXXXXXXX; end
        if (op == 6'b110111) begin linha <= 33'bXXXX11XXX0XXXXXXXXXXXXX00XXXXXXXX; end

        // SC
        if (op == 6'b111000) begin
            linha <= 33'b1000000011X0XX0100XXXXX0111001010;
            // $display(">>> Instruction: SC;");
        end

        // Undefined
        if (op == 6'b111001) begin linha <= 33'bXXXX11XXX0XXXXXXXXXXXXX00XXXXXXXX; end
        if (op == 6'b111010) begin linha <= 33'bXXXX11XXX0XXXXXXXXXXXXX00XXXXXXXX; end
        if (op == 6'b111011) begin linha <= 33'bXXXX11XXX0XXXXXXXXXXXXX00XXXXXXXX; end
        if (op == 6'b111100) begin linha <= 33'bXXXX11XXX0XXXXXXXXXXXXX00XXXXXXXX; end
        if (op == 6'b111101) begin linha <= 33'bXXXX11XXX0XXXXXXXXXXXXX00XXXXXXXX; end
        if (op == 6'b111110) begin linha <= 33'bXXXX11XXX0XXXXXXXXXXXXX00XXXXXXXX; end
        if (op == 6'b111111) begin linha <= 33'bXXXX11XXX0XXXXXXXXXXXXX00XXXXXXXX; end

    end

endmodule
